package com.lovi.service;

import com.lovi.common.Message;
import com.lovi.common.MessageType;
import com.lovi.common.User;
import com.lovi.thread_.ClientConnectServerThread;
import com.lovi.thread_.ManageClientConnectServerThread;
import com.lovi.utils.StreamUtils;
import org.junit.Test;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

/**
 * 需要客户端发送对象流给服务端,接收服务端传过来的登录成功/失败
 *
 */
public class QQServiceImpl {
    private User user = new User();
    //需要客户端发送对象流给服务端,接收服务端传过来的登录成功/失败
    public boolean login(String userId, String pwd) throws IOException, ClassNotFoundException {
        Socket socket;
        //服务端是9999端口，连接端口得到socket
        socket = new Socket(InetAddress.getByName("127.0.0.1"),9999);
        user.setPassword(pwd);
        user.setUserId(userId);
        //对象流，发送给服务器
        ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
        oos.writeObject(user);
        //这里不设置结束标志是因为待会还要和服务端保持相互通信
        //接收服务端传过来的登录成功/失败（也是对象的形式）
        ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
        Message data = (Message)ois.readObject();
        if (MessageType.LOGIN_SUCCESS.equals(data.getMestype())) {
            //登录成功
            /*
                在登录成功之后开启线程的主要目的是为了不阻塞主线程（例如UI线程），并且能够持续
                监听服务器的消息。这并不意味着如果不开启线程，服务器的9999端口就会被单一的socket占用而无法再接受其他连接。
                socket每个客户端连接是独立的，它们不会因为没有为每个连接开启线程而影响其他连接。
                重点：开启子线程是为了让客户端可以异步处理网络通信，从而保持应用程序的响应性，并允许并发处理多个任务。
             */
            //开启一个客户端和服务端连接通信的线程 ClientConnectServerThread
            //目的是：ClientConnectServerThread.start()[可以继承也可以接口]
            ClientConnectServerThread connectServerThread = new ClientConnectServerThread(socket);
            //开启线程
            connectServerThread.start();
            //为了方便后续扩展，我们需要管理一堆线程
            ManageClientConnectServerThread.addClientConnectServerThread(userId,connectServerThread);
            return true;
        } else if (MessageType.LOGIN_FAIL.equals(data.getMestype())) {
            //登录失败,关闭socket
            socket.close();
            return false;
        }
        return false;
    }

    /**
     * 获取当前用户列表
     */
    public void getOnlineUser() {
        //1. 发送一个获取在线用户列表的消息给服务器
        Message message = new Message();
        message.setMestype(MessageType.MESSAGE_GET_ONLINE_FRIEND);
        //拿到当前线程
        ClientConnectServerThread currentThread = ManageClientConnectServerThread.getClientConnectServerThread(user.getUserId());
        Socket socket2 = currentThread.getSocket();
        // 设置发送者
        message.setSender(user.getUserId());
        System.out.println("用户"+user.getUserId()+"正在请求获取用户列表");
        ObjectOutputStream oos;
        ObjectInputStream ois;
        //发送
        try {
           oos  = new ObjectOutputStream(socket2.getOutputStream());
           oos.writeObject(message);
           //接收，读取服务器的用户列表
//            ois = new ObjectInputStream(socket2.getInputStream());
//            Message message2 = (Message) ois.readObject();
//            if(MessageType.MESSAGE_GET_ONLINE_FRIEND.equals(message2.getMestype())){
//                String content = message2.getContent();
//                String[] s = content.split(" ");
//                System.out.println("=====当前在线用户列表=====");
//                for (String value : s) {
//                    System.out.println(value);
//                }
//            }
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    /**
     * 退出系统，发送退出系统的信号给服务器
     */

    public void quit() {
        ClientConnectServerThread thread
                = ManageClientConnectServerThread.getClientConnectServerThread(user.getUserId());
        Message message = new Message();
        message.setMestype(MessageType.MESSAGE_CLIENT_EXIT);
        message.setSender(user.getUserId());
        try {
            ObjectOutputStream oos = new ObjectOutputStream(thread.getSocket().getOutputStream());
            oos.writeObject(message);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 发送私聊消息给服务端
     */

    public void privateChat(String getterUserId,String content) {
        //用户发送私聊消息信号给服务端,设置好发送者,接受者,发送的内容,消息类型
        Message message = new Message();
        message.setSender(user.getUserId());
        message.setGetter(getterUserId);
        message.setContent(content);
        message.setTime(formatDate());
        message.setMestype(MessageType.MESSAGE_COMM_MES);
        ClientConnectServerThread thread = ManageClientConnectServerThread.getClientConnectServerThread(user.getUserId());
        try {
            ObjectOutputStream oos = new ObjectOutputStream(thread.getSocket().getOutputStream());
            oos.writeObject(message);
        } catch (IOException e) {
            System.out.println("发送私聊消息异常："+e.getMessage());
        }
    }

    /**
     * 发送文件到服务器
     * @param getterUserId2
     * @param filePath
     */
    public void sendFile(String getterUserId2, String filePath,String targetFilePath) {
        try {
            Message message = new Message();
            message.setSender(user.getUserId());
            message.setGetter(getterUserId2);
            message.setTime(formatDate());
            message.setMestype(MessageType.MESSAGE_FILE_MES);
            message.setFileBytes(StreamUtils.streamToBytes(new FileInputStream(filePath)));
            message.setTargetFilePath(targetFilePath);
            ClientConnectServerThread thread = ManageClientConnectServerThread
                    .getClientConnectServerThread(user.getUserId());
            ObjectOutputStream oos = new ObjectOutputStream(thread.getSocket().getOutputStream());
            oos.writeObject(message);
        } catch (IOException e) {
            System.out.println("发送文件异常："+e.getMessage());
        }
    }
    public String formatDate(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(new Date());
    }

    /**
     * 群发消息
     * @param conntent2
     */
    public void groupChat(String content2) {
        Message message = new Message();
        message.setSender(user.getUserId());
        message.setContent(content2);
        message.setTime(formatDate());
        message.setMestype(MessageType.MESSAGE_TO_ALL_MES);
        ClientConnectServerThread thread = ManageClientConnectServerThread.getClientConnectServerThread(user.getUserId());
        try {
            ObjectOutputStream oos = new ObjectOutputStream(thread.getSocket().getOutputStream());
            oos.writeObject(message);
        } catch (IOException e) {
            System.out.println("发送群发消息异常："+e.getMessage());
        }
    }

    /**
     * 获取当前用户的离线消息
     * @param userId
     */
    public void getOffLineMessage(String userId) {
        Message message = new Message();
        message.setSender(user.getUserId());
        message.setMestype(MessageType.MESSAGE_OFFLINE_MES);
        ClientConnectServerThread thread = ManageClientConnectServerThread.getClientConnectServerThread(user.getUserId());
        try {
            ObjectOutputStream oos = new ObjectOutputStream(thread.getSocket().getOutputStream());
            oos.writeObject(message);
        } catch (IOException e) {
            System.out.println("请求离线消息异常："+e.getMessage());
        }
    }
}
